﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
using IotClient.Entity;
using IotClient.Unity;
using IotClient.VM;
using IotControl.Base;
using IotControl.Models;
using LiveCharts;
using LiveCharts.Defaults;
using LiveCharts.Wpf;

namespace IotControl.ViewModels
{
    public class MainViewModel : NotifyBase
    {
        public SeriesCollection StateSeries { get; set; }
        public ChartValues<ObservableValue> YeildValues1 { get; set; }
        public ChartValues<ObservableValue> YeildValues2 { get; set; }

        public List<CompareItemModel> WorkerCompareList { get; set; }

        public List<CompareItemModel> QualityList { get; set; }

        public ObservableCollection<string> Alarms { get; set; }

        //public string CurrentYeild { get; set; } = "123456";
        private string _currentYeild;
        public string CurrentYeild
        {
            get { return _currentYeild; }
            set { SetProperty(ref _currentYeild, value); }
        }
        public int FinishRate { get; set; } = 0;

        public List<BadItemModel> BadScatter { get; set; }

        Random random = new Random();
        CancellationTokenSource cts = new CancellationTokenSource();
        Task task = null;
        string[] FalutName = new string[4] { "模块故障", "电源故障", "建模故障", "其他" };
        public ControlSetting Setting
        {
            get => MQTTUnity.Setting as ControlSetting;
            set => MQTTUnity.Setting = value;
        }
        public MQTTUnity MQTTUnity { get; set; } = new MQTTUnity();
        public Action<string, bool> LogCall
        {
            get => MQTTUnity.LogCall;
            set => MQTTUnity.LogCall = value;
        }

        public MainViewModel()
        {
            #region 环状图数据初始化
            StateSeries = new SeriesCollection();
            StateSeries.Add(
                new PieSeries()
                {
                    Title = FalutName[0],
                    Values = new ChartValues<double>(new double[] { 0.1 }),
                    Fill = new SolidColorBrush(Color.FromArgb(255, 43, 182, 254)),
                }
            );
            StateSeries.Add(
                new PieSeries()
                {
                    Title = FalutName[1],
                    Values = new ChartValues<double>(new double[] { 0.2 }),
                    Fill = Brushes.Red,
                }
            );
            StateSeries.Add(
                new PieSeries()
                {
                    Title = FalutName[2],
                    Values = new ChartValues<double>(new double[] { 0.1 }),
                    Fill = new SolidColorBrush(Color.FromArgb(255, 144, 150, 191)),
                }
            );
            StateSeries.Add(
                new PieSeries()
                {
                    Title = FalutName[3],
                    Values = new ChartValues<double>(new double[] { 0.1 }),
                    Fill = Brushes.DimGray,
                }
            );
            #endregion

            #region 人员绩效初始化
            string[] Empolys = new string[] { "王工", "张工", "孙工", "李工", "周工" };
            WorkerCompareList = new List<CompareItemModel>();
            foreach (var e in Empolys)
            {
                WorkerCompareList.Add(
                    new CompareItemModel()
                    {
                        Name = e,
                        PlanValue = random.Next(100, 200),
                        FinishedValue = random.Next(10, 150),
                    }
                );
            }

            #endregion

            #region 报警数据初始化
            Alarms = new ObservableCollection<string>();
            //Alarms.Add("【H338->厂务冷却水入水温度[℃]】 34->10:00");
            //Alarms.Add("【H338->厂务冷却水入水温度[℃]】 34->10:00");
            //Alarms.Add("【H338->厂务冷却水入水温度[℃]】 34->10:00");
            //Alarms.Add("【H338->厂务冷却水入水温度[℃]】 34->10:00");
            #endregion

            YeildValues1 = new ChartValues<ObservableValue>();
            YeildValues2 = new ChartValues<ObservableValue>();
            for (int i = 0; i < 12; i++)
            {
                YeildValues1.Add(new ObservableValue(random.Next(20, 380)));
                YeildValues2.Add(new ObservableValue(random.Next(20, 300)));
            }

            #region 不良分布初始化
            BadScatter = new List<BadItemModel>();
            string[] BadNames = new string[]
            {
                "等级A",
                "等级B",
                "等级C",
                "等级D",
                "等级E",
                "等级E",
                "等级F",
                "等级G",
            };
            for (int i = 0; i < BadNames.Length; i++)
            {
                BadScatter.Add(
                    new BadItemModel()
                    {
                        Title = BadNames[i],
                        Size = 180 - 20 * i,
                        Value = 0.9 - 0.1 * i,
                    }
                );
            }
            #endregion

            #region 质量控制
            string[] quality = new string[]
            {
                "设备-1",
                "设备-2",
                "设备-3",
                "设备-4",
                "设备-5",
                "设备-6",
                "设备-7",
                "设备-8",
                "设备-9",
                "设备-10",
            };
            QualityList = new List<CompareItemModel>();
            foreach (var q in quality)
            {
                QualityList.Add(
                    new CompareItemModel()
                    {
                        Name = q,
                        PlanValue = random.Next(100, 200),
                        FinishedValue = random.Next(10, 150),
                    }
                );
            }
            #endregion

            //TcpClient tcpClient = new TcpClient();
            //tcpClient.Connect("127.0.0.1", 502);
            //Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(tcpClient);
            //task = Task.Run(async () =>
            //{
            //    while (!cts.IsCancellationRequested)
            //    {
            //        await Task.Delay(1000);
            //        // 持续获取现场数据
            //        ushort[] values = master.ReadHoldingRegisters(1, 0, 1);
            //        CurrentYeild = values[0].ToString("000000");

            //        // 添加报警
            //        Application.Current.Dispatcher.Invoke(() =>
            //        {
            //            Alarms.Insert(0, "【H338->厂务冷却水入水温度[℃]】 34->20:00");
            //            if (Alarms.Count > 6)
            //                Alarms.RemoveAt(Alarms.Count - 1);// 滚动   停留
            //        });
            //    }
            //}, cts.Token);
            MQTTUnity.Setting = new ControlSetting();
            Setting.ClientID = "Dash";
            Setting.ConnentCall = MQTTUnity.ConnentCall;
            //Connect();
            LogCall?.Invoke($"【已初始化】", true);
        }

        public void Connect()
        {
            try
            {
                Setting.Enable = true;
                MQTTUnity.StartSubscribe(Setting.SubTopic);
                MQTTUnity.OnReceived = OnReceived;
                Application.Current.Dispatcher.Invoke(() =>
                {
                    LogCall($"【已连接服务器】{Setting.SubTopic}", true);
                });
            }
            catch (Exception ex)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    LogCall($"【初始化异常】{ex.Message}", true);
                });
            }
        }

        private void OnReceived(DeviceDataPack pack, string ID)
        {
            if (pack != null && pack.data != null)
            {
                UpdateCode(pack.data.status, ID);
            }
        }

        int[] TypeCount = new int[4];
        public int FalutCount { get; set; } = 0;

        public void UpdateCode(int code, string ID = null)
        {
            if (ID != null)
                Application.Current.Dispatcher.Invoke(() =>
                {
                    LogCall($"【故障发生】设备{ID} ，故障代码{code}", true);
                });
            var count = 0;
            for (int i = 0; i < TypeCount.Length; i++)
            {
                if (((code >> i) & 0x1) != 0)
                {
                    TypeCount[i]++;
                }
                count += TypeCount[i];
            }
            FalutCount = count;
            Application.Current.Dispatcher.Invoke(() =>
            {
                for (int i = 0; i < TypeCount.Length; i++)
                {
                    if (FalutCount > 0)
                        StateSeries[i].Values = new ChartValues<double>(
                            new double[] { 1.0 * TypeCount[i] / FalutCount }
                        );
                }
            });
        }

        public void Dispose()
        {
            cts.Cancel();
            Task.WaitAny(task);
        }
    }
}
